package uba.algo3.tp3.tsp;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Random;
import java.util.StringTokenizer;
import org.junit.Test;

public class TestStress
{
		  static Grafo g;
		  int tpoExpiracion = 7;
		  int tolerancia = 300;
		  int diversificacion = 8;
		  int[] tolerancias = new int[6];
		  int[] tiempos = new int[16];
		  int[] tiemposD = new int[16];
		  int[] diversificaciones = new int[11];
		  int toleranciaMax = 0;
		  
		  @Test
		  public void TestAzar() throws IOException{
			  
		   	  int i = 10;
			  int i_orig = 10;
		      //BufferedWriter os = new BufferedWriter( new FileWriter( "Tp3BusquedaTabu.out" ) );
		  	  //BufferedWriter os = new BufferedWriter( new FileWriter( getClass().getResource( "" ).getPath() + "testRendExactoM.out" ) ); //me tira FileNotFoundException!
		  	  
		   	  BufferedReader is;
		  	  BufferedWriter Dos, Tos;
		  	  
		      String line;
		      int cantidadDeGrafos = 40;
		      
		      while(i <= i_orig + cantidadDeGrafos)
		      {
		    	  
		    	  //System.out.println(i);
		    	  for(int j = 1;j <= 1;j++)
		    	  {
			    	  crearGrafo(i);
			    	  
			    	  is = new BufferedReader( new InputStreamReader( getClass().getResourceAsStream( "grafo" + i + ".in" ) ) );
			    	  Dos = new BufferedWriter( new FileWriter( getClass().getResource( "" ).getPath() + "grafoD" + i + ".out" ) ); //me tira FileNotFoundException!
			    	  Tos = new BufferedWriter( new FileWriter( getClass().getResource( "" ).getPath() + "grafoT" + i + ".out" ) );
			    	  line = is.readLine();

			    	  leer(line,is);
			    	  
			    	  testTolerancia();
			    	  testExpiracion();
			    	  testDiversificacion();
			    	  testTiempos();
		    	  
		    	  }

			      i++;
		      }
		      
		      /*
		      System.out.println("ToleranciaMax = " + toleranciaMax);
		      System.out.println("Tolerancias:");
		      for(int j = 0;j < tolerancias.length;j++)
		      {
			      System.out.println(tolerancias[j]);    	  
		      }

		      
		      System.out.println("Tiempos:");
		      for(int j = 0;j < tiempos.length;j++)
		      {
			      System.out.println(tiempos[j]);    	  
		      }

		      		      
		      
		      System.out.println("Diversificaciones:");
		      for(int j = 0;j < diversificaciones.length;j++)
		      {
			      System.out.println(diversificaciones[j]);    	  
		      }
		      */

			  
		  }
		
		private void testTiempos()
		{
	    	  BusquedaTabuD b = new BusquedaTabuD(g);
	    	  BusquedaLocal loc = new BusquedaLocal(g);
	    	  Constructiva c = new Constructiva(g);
	    	  
	    	  long l;
	    	  int tiempo_promedio_b = 0;
	    	  int tiempo_promedio_l = 0;
	    	  int tiempo_promedio_c = 0;
	    	  
	    	  for(int i = 0; i < 5;i++)
	    	  {
	    		  
	    		  l = System.currentTimeMillis();
	    		  Solucion s = b.get2TSP(7,300,8);
	    		  tiempo_promedio_b += (int) (System.currentTimeMillis() - l);
	    		  
	    		  /*
	    		  l = System.currentTimeMillis();
	    		  Solucion s = loc.get2TSP();
	    		  tiempo_promedio_l += (int) (System.currentTimeMillis() - l);
	    		  
	    		  l = System.currentTimeMillis();
	    		  s = c.get2TSP();
	    		  tiempo_promedio_c += (int) (System.currentTimeMillis() - l);*/
	    	  }
	    	  
	    	  //System.out.println(g.n + " " + tiempo_promedio_l/5 + " " + tiempo_promedio_c/5);
	    	  System.out.println(g.n + " " + tiempo_promedio_b/5);
		}

		private void testDiversificacion()
		{
	    	  BusquedaTabuD b = new BusquedaTabuD(g);

	    	  int temp;
	    	  int min = Integer.MAX_VALUE;
	    	  int diversificacionMenor = 0;

		  	for(int i = 0; i <= 10;i++)
    	 	{
	    		  Solucion s = b.get2TSP(7,300,i);

	    		  temp = s.getCosto();
	    		  
	    		  if(temp < min)
	    		  {
	    			  min = temp;
	    			  diversificacionMenor = i;
	    		  }
    		  }
	    	  
	    	  diversificaciones[diversificacionMenor]++;
	    	  
	    	  System.out.println("Tiempo de diversificacion menor: " + diversificacionMenor);		
		}

		private void testExpiracion()
		{
	    	  BusquedaTabuD b = new BusquedaTabuD(g);
	    	  
	    	  int temp;
	    	  int min = Integer.MAX_VALUE;
	    	  int tiempoExpiracion = 0;
	    	  int costoAnterior = Integer.MAX_VALUE;
	    	  int[] tiemposMinimos = new int[16];
	    	  
	    	  for(int i = 0; i < 15;i++)
	    	  {
	    		  Solucion s = b.get2TSP(i,300,0);

	    		  temp = s.getCosto();
	    		  
	    		  if(temp < min)
	    		  {
	    			  min = temp;
	    			  tiempoExpiracion = i;
	    			  tiemposMinimos = new int[16];
	    			  tiemposMinimos[i] = 1;
	    		  }
	    		  if(temp == min)
	    		  {
	    			  tiemposMinimos[i] = 1;
	    		  }
	    		  //System.out.println("tiempoExpiracion = " + i + "   costo = " + temp);
	    		  costoAnterior = temp;
	    	  }
	    	  
	    	  for(int i = 0; i < 15;i++)
	    	  {
	    		  if(tiemposMinimos[i]  == 1)
	    		  {
	    	    	  tiempos[i]++;
	    	    	  System.out.println("Tiempo de expiracion menor: " + i + " para costo : " + min);
	    		  }
	    	  }


			
		}

		private void testTolerancia() throws IOException
		{
	    	  BusquedaTabuD b = new BusquedaTabuD(g);
	    	  
	    	  int temp;
	    	  int min = Integer.MAX_VALUE;
	    	  int toleranciaNecesitada = 0;
	    		  
	    	  for(int i = 50; i < 1000;i+=50)
	    	  {
	    		  Solucion s = b.get2TSP(tpoExpiracion,i,0);
	    		  
	    		  temp = s.getCosto();
	    		  if(temp < min)
	    		  {
	    			  min = temp;
	    			  toleranciaNecesitada = i;
	    		  }
	    	  }
	    	  
	    	  if(toleranciaNecesitada <= 50)
	    	  {
	    		  tolerancias[0]++;
	    	  }
	    	  else
	    	  {
	    		  if(toleranciaNecesitada <= 100)
	    		  {
	    			  tolerancias[1]++;
	    	    	  System.out.println(g.getN() + " " + toleranciaNecesitada);
	    		  }
	    		  else
	    		  {
	    			  if(toleranciaNecesitada <= 150)
	    			  {
	    				  tolerancias[2]++;
	    		    	  System.out.println(g.getN() + " " + toleranciaNecesitada);
	    			  }
	    			  else
	    			  {
	    				  if(toleranciaNecesitada <= 200)
	    				  {
		    				  tolerancias[3]++;
		    		    	  System.out.println(g.getN() + " " + toleranciaNecesitada);
	    				  }
	    				  else
	    				  {
	    					  tolerancias[4]++;
		    				  if(toleranciaNecesitada > toleranciaMax)
		    				  {
		    					  toleranciaMax = toleranciaNecesitada;
		    				  }
	    				  }

	    			  }
	    		  }
	    	  }


	    }

		private void crearGrafo(int i) throws IOException
		{
			  BufferedWriter os = new BufferedWriter( new FileWriter( getClass().getResource( "" ).getPath() + "grafo" + i + ".in" ) ); //me tira FileNotFoundException!
			  String line = "";
			  //FALTA PRIMERA LINEA CON EL NODO ORIGEN Y CANTIDAD DE NODOS
			  Random r = new Random();
			  
			  int temp = r.nextInt(i) + 1;
			  
			  line = line + Integer.toString(i) + " ";
			  line = line + Integer.toString(temp);
			  
			  os.append(line);
			  
			  os.newLine();
			  
			  for(int j = 0; j < i-1; j++)
			  {
				  line = "";
				  
				  for(int k = 0; k < j;k++)
				  {
					  temp = r.nextInt(i*10) + 1;
					  line = line + Integer.toString(temp) + " ";
				  }
				  
				  temp = r.nextInt(i*10) + 1;
				  line = line + Integer.toString(temp);
				  os.append(line);
				  if(j!=i-1)
				  {
				      os.newLine();
				  }
				  
			  }
			  
			  os.close();
		}

		public void leer(String line_param, BufferedReader is) throws IOException{
				  
				String line;

			  StringTokenizer st1 = new StringTokenizer(line_param, " ");
			  String cantNodos = st1.nextToken();
			  String nodoOrig_str = st1.nextToken();
				  
			  int n = Integer.parseInt(cantNodos);
			  int nodoOrig = Integer.parseInt(nodoOrig_str);
			  g = new Grafo(n, nodoOrig);
			  int temp;
			  
			  for(int i = 0; i < n-1; i++)
			  {
				  line = is.readLine();
				  st1 = new StringTokenizer(line, " ");
			      int j = i+1;
				  int k = 0;
				  while(st1.hasMoreTokens())
				  {
					  String s = st1.nextToken();
					  temp = Integer.parseInt(s);
					  g.matriz[k][j] = temp;
					  g.matriz[j][k] = temp;
					  k++;
				  }
			  }
		  }
			  
		  public void escribir(Solucion s, BufferedWriter os) throws IOException{
			      //escribo el archivo de salida
			      ArrayList<Integer> ciclo1 = s.getCiclo1();
			      String solCiclo1 = formatearSalida(ciclo1);
			      ArrayList<Integer> ciclo2 = s.getCiclo2();
			      String solCiclo2 = formatearSalida(ciclo2);
			      
			      os.append(solCiclo1);
			      os.newLine();
			      os.append(solCiclo2);
			      os.newLine();
		  }
		  
		  private String formatearSalida(ArrayList<Integer> a){
				String res = new String();
				a.remove(0); //le saco el nodo de origen
				for(Integer e : a){
					res+=e;
					res+=" ";
				}
				return res;	
			}

		  
	/*	   @Test
		   public void fileWritingRunTest() throws IOException {
		      // Con este test se lee el archivo de entrada proporcioando por la catedra 
		      // y se genera la salida.
		      
		      BufferedReader is = new BufferedReader( new InputStreamReader( getClass().getResourceAsStream( "Tp3BusquedaLocalOptima.in" ) ) );
		      BufferedWriter os = new BufferedWriter( new FileWriter( getClass().getResource( "" ).getPath() + "Tp3BusquedaTabuOptima.out" ) );

		      String line;
		      
		      line = is.readLine();
		      
		      while(line != null)
		      {
				  StringTokenizer st1 = new StringTokenizer(line, " ");
				  String cantNodos = st1.nextToken();
				  String nodoOrig_str = st1.nextToken();
				  
				  int n = Integer.parseInt(cantNodos);
				  int nodoOrig = Integer.parseInt(nodoOrig_str);
				  g = new Grafo(n, nodoOrig);
				  int temp;
				  for(int i = 0; i < n-1; i++)
				  {
					  line = is.readLine();
					  
					  st1 = new StringTokenizer(line, " ");
					  int j = i+1;
					  int k = 0;
					  while(st1.hasMoreTokens())
					  {
						  String s = st1.nextToken();
						  temp = Integer.parseInt(s);
						  g.matriz[k][j] = temp;
						  g.matriz[j][k] = temp;
						  k++;
					  }
				  }
				  
			      BusquedaTabu b = new BusquedaTabu(g);
			      
			      Solucion s = b.get2TSP(5,10000);
				  
			      //escribo el archivo de salida
			      ArrayList<Integer> ciclo1 = s.getCiclo1();
			      String solCiclo1 = formatearSalida(ciclo1);
			      ArrayList<Integer> ciclo2 = s.getCiclo2();
			      String solCiclo2 = formatearSalida(ciclo2);
			      
			      os.append(solCiclo1);
			      os.newLine();
			      os.append(solCiclo2);
			      os.newLine();
			      
				  line = is.readLine();
		      }
		 
		      os.close();
		      
		   }
	*/   	  

}
